<template>
<vue-progress :percent.sync="progress.percent" :options="progress.options"></vue-progress>
<div class="row">
  <div class="col-md-12">
    <my-navbar>
      <template slot="left"> 
        <connect-server 
          @ev-connected="onConnected" 
          @ev-disconnected="onDisconnected"></connect-server>
      </template>
      <template slot="right">  
        <div v-if="connect">
          <div class="form-group">
            <label class="control-label">LCD</label>
            <select class="form-control" v-model="topoIdOfLcd" @change.prevent="onLcdChange">
              <option v-for="option in lcdOptions" :value="option.value">{{option.text}}</option>
            </select>
          </div>
          <button class="btn btn-default" @click.prevent="onShowLocation">
            <span class="glyphicon glyphicon-retweet"></span> {{$t('common.showlocation')}}
          </button>   
          <button class="btn btn-default" @click.prevent="onClearLocation">
            <span class="glyphicon glyphicon-retweet"></span> {{$t('common.clearlocation')}}
          </button>
          <button class="btn btn-default" @click.prevent="onSyncBackground">
            <span class="glyphicon glyphicon-retweet"></span> {{$t('common.syncToDevs')}}
          </button>           
        </div>       
      </template> 
    </my-navbar>
  </div>
  <my-img-upload :multi-screen="multiScreen" :do-submit="doSubmit" v-if="connect"></my-img-upload>
</div>
</template>

<script>
import _ from 'lodash'
import async from 'async'
import ebus from 'libs/ebus.js'
import toast from 'libs/toast.js'
import msgbox from 'libs/msgbox.js'
import {mediaPhyApi, storageApi} from 'share/server/api.js'
import store from 'share/server/vuex/store.js'
import {getMultiScreenOfLcd} from 'share/server/utils.js'
import {devsOfLcd} from 'share/server/vuex/getters.js'
import {setLcdTopoDev} from 'share/server/vuex/actions/multimedia.js'
import ConnectServer from 'share/server/components/ConnectServer.vue'

export default {
  store,
  components: {
    'connect-server': ConnectServer
  },
  vuex: {
    getters: {
      devsOfLcd,
      lcdTopoDev: (state) => state.lcd.topoDev
    },
    actions: {
      setLcdTopoDev
    }
  },
  data () {
    return {
      progress: {
        percent: 0,
        options: {
          show: true,
          canSuccess: true,
          color: 'rgb(143, 255, 199)',
          failedColor: 'red',
          height: '2px'
        }        
      },
      connect: false,
      multiScreen: {
        x: 1,
        y: 1
      }
    }
  },
  computed: {
    lcdOptions () {
      return _.map(this.devsOfLcd, (item) => {
        return {
          text: item.devName,
          value: item.topoId
        }
      })      
    },
    topoIdOfLcd: {
      get () {
        return this.lcdTopoDev.topoId
      },
      set (val) {
        let topoDev = _.find(this.devsOfLcd, {topoId: val})
        this.setLcdTopoDev(topoDev)
      }
    }   
  },
  methods: {
    onUploadAbort (e) {
      toast.e(this, this.$t('common.fail'), this.$t('error.abort'))
    },
    onUploadTimeout (e) {
      toast.e(this, this.$t('common.fail'), this.$t('error.timeout'))
    },    
    stepUploadScreenBg(task, dataUrl, cb) {
      storageApi.uploadFile('topoConfig', 
        `${this.topoIdOfLcd}-${task.index}-background.json`, 
        JSON.stringify({
          dataURL: dataUrl
        }), {
          onabort: this.onUploadAbort,
          ontimeout: this.onUploadTimeout
        }).then(function(res) {
          if (res && res.data && res.data.code === 0) {
            cb(null)
            this.$progress.set(95 * (task.index + 1)/task.total)
          } else {
            cb({msg: `code[${res.data.code}]`})
          }
        }.bind(this), function(res) {
          cb({msg: this.$t('error.noResponse')})
        }.bind(this))
    },
    stepGenScreenBg (task, cb) {
      let lcdbg = task.lcdbg

      let dataUrl = lcdbg.stage.toDataURL({
        mimeType: 'image/jpeg',
        quality: 1,
        x: task.x * 1920,
        y: task.y * 1080,
        width: 1920,
        height: 1080
      })
      cb(null, task, dataUrl)
    },
    makeScreenBg (task, callback) {
      async.waterfall([
        function(cb) {
          cb(null, task)      
        }, 
        this.stepGenScreenBg,
        this.stepUploadScreenBg,
        ], 
        function (err, result) {
          callback(err)
        }
      )
    },
    onUploadSuccess () {
      msgbox.alert({
        title: this.$t('common.success'),
        text: this.$t('alert.plzSyncToDevs'),
        type: "success",
        showCancelButton: true,
        confirmButtonColor: "#DD6B55",
        cancelButtonText: this.$t('common.cancel'),
        confirmButtonText: this.$t('common.confirm'),
        closeOnConfirm: true        
      }, 
      function() {
        this.onSendCmd('syncBackground')
      }.bind(this))
    },    
    doSubmit (lcdbg, cb) {
      var x, y
      var index = 0
      var tasks = []
      let total = this.multiScreen.x * this.multiScreen.y
      this.$progress.start(3000)
      if (total > 4) {
        msgbox.showWait(this.$t('alert.plzWait'), this.$t('common.processing'), -1)
      }
      for (y = 0; y < this.multiScreen.y; y++) {
        for (x = 0; x < this.multiScreen.x; x++) {
          tasks.push({x, y, index, total, lcdbg})
          index++
        }
      }
      async.eachSeries(tasks, this.makeScreenBg, function(err) {
        cb()
        this.$progress.finish()
        if (err) {
          msgbox.close()
          toast.e(this, this.$t('common.fail'), err.msg)
        } else {
          this.onUploadSuccess()
        }
      }.bind(this))
    },
    onLcdChange () {
      let multiScreen = getMultiScreenOfLcd(this.lcdTopoDev.devModel)
      this.multiScreen.x = multiScreen.x
      this.multiScreen.y = multiScreen.y
      ebus.emit('draw-preview')
    },
    onSendCmd (cmd) {
      if (this.topoIdOfLcd > 0) {
        mediaPhyApi.setDevId(this.topoIdOfLcd)
        mediaPhyApi.sendCmd(cmd).then(function(res) {
          if (res && res.data && res.data.code === 0) {
            toast.s(this, this.$t('common.success'), this.$t('msg.sendCmdSuccess'))
          } else {
            toast.code(this, res.data)
          }          
        }.bind(this))
      } 
    },
    onShowLocation () {
      this.onSendCmd('showLocation')    
    },
    onClearLocation () {
      this.onSendCmd('clearLocation')    
    },
    onSyncBackground () {
      this.onSendCmd('syncBackground')
    },
    onDisconnected () {
      this.setLcdTopoDev({
        topoId: -1
      })
      this.connect = false
    },
    onConnected () {
      this.connect = true
    },
  },
  ready () {
    this.$progress.setHolder(this.progress)
  }
}
</script>

<style>
</style>